// License: GPL. For details, see LICENSE file.
package de.unistuttgart.iev.osm.bboxchooser;

import java.awt.BorderLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;

/**
 * This component allows the user to choose a bounding box using a map widget or
 * four text fields.
 * 
 * @author Igor Podolskiy
 */
public class BBoxChooserPanel extends JPanel {

	private static final long serialVersionUID = 1L;

	private SlippyMapBBoxChooser bboxChooser;
	private BBoxDisplay bboxDisplay;
	private boolean processBboxChangeEvent = true;

	/**
	 * Creates a bounding box chooser panel with the default cache directory.
	 */
	public BBoxChooserPanel() {
		this(null);
	}

	/**
	 * Creates a bounding box chooser panel with the specified cache directory.
	 * 
	 * @param cacheDir
	 *            the directory to store the cached tiles in.
	 */
	public BBoxChooserPanel(File cacheDir) {
		createGUI(cacheDir);
	}

	private void createGUI(File cacheDir) {
		bboxChooser = new SlippyMapBBoxChooser(cacheDir);
		bboxDisplay = new BBoxDisplay();

		setLayout(new BorderLayout());
		setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));

		JPanel panel = new JPanel();
		panel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
		add(panel, BorderLayout.CENTER);

		panel.setLayout(new BorderLayout());
		panel.add(bboxChooser, BorderLayout.CENTER);

		bboxChooser.setToolTipText(Messages
				.getString("BBoxChooserPanel.ToolTip")); //$NON-NLS-1$

		Box controlBox = Box.createVerticalBox();
		controlBox.add(Box.createVerticalStrut(5));
		controlBox.add(bboxDisplay);
		controlBox.add(Box.createVerticalStrut(5));

		panel.add(controlBox, BorderLayout.SOUTH);

		bboxChooser.addPropertyChangeListener(new PropertyChangeListener() {

			@Override
			public void propertyChange(PropertyChangeEvent evt) {
				if (!processBboxChangeEvent
						|| !evt.getPropertyName().equals(BBoxChooser.BBOX_PROP)) {
					return;
				}
				try {
					processBboxChangeEvent = false;
					bboxDisplay.setBoundingBox(bboxChooser.getBoundingBox());
				} finally {
					processBboxChangeEvent = true;
				}
			}
		});

		bboxDisplay.addPropertyChangeListener(new PropertyChangeListener() {

			@Override
			public void propertyChange(PropertyChangeEvent evt) {
				if (!processBboxChangeEvent
						|| !evt.getPropertyName().equals(BBoxDisplay.BBOX_PROP)) {
					return;
				}
				try {
					processBboxChangeEvent = false;
					bboxChooser.setBoundingBox(bboxDisplay.getBoundingBox());
				} finally {
					processBboxChangeEvent = true;
				}
			}
		});
	}

	/**
	 * Sets the bounding box to be selected in the panel.
	 * 
	 * @param bbox
	 *            the bounding box.
	 */
	public void setBoundingBox(Bounds bbox) {
		bboxChooser.setBoundingBox(bbox);
	}

	/**
	 * Gets the bounding box currently selected in the panel.
	 * 
	 * @return the selected bounding box
	 */
	public Bounds getBoundingBox() {
		return bboxChooser.getBoundingBox();
	}

}
